#include "qqmusic.h"
#include "ui_qqmusic.h"
#include"volumetool.h"
#include<QDebug>
#include<QJsonArray>
#include<QMouseEvent>
#include<QGraphicsDropShadowEffect>
#include<QFileDialog>
#include<QDir>
#include<QSqlError>
#include<QSqlQuery>
#include<QMessageBox>
#include<QSystemTrayIcon>
#include<QMenu>

///////////////////////////////////////////////////////
//整个音乐播放器界面//////////////////////////////////////
//////////////////////////////////////////////////////

//没有歌词
QQMusic::QQMusic(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::QQMusic)
{
    ui->setupUi(this);
    //初始化音乐播放器的UI主界面
    InitUI();
    //初始化数据库的方法
    InitSqlite();
    //初始化不同页面的歌曲音乐列表(从数据库中读取数据并初始化不同页面的音乐列表)
    InitMusicList();
    //初始化媒体播放
    initPlayer();
    //处理所有的信号和槽函数的关联
    connectSignalsAndSlots();
}

QQMusic::~QQMusic()
{
    delete ui;
}

//初始化音乐播放器的UI主界面
void QQMusic::InitUI()
{
    //设置无标题栏
    this->setWindowFlag(Qt::WindowType::FramelessWindowHint);
    //设置窗口透明
    this->setAttribute(Qt::WA_TranslucentBackground);
    //设置窗口图标
    setWindowIcon(QIcon(":/image/tubiao.png"));
    //添加系统托盘并设置托盘图片
    QSystemTrayIcon* trayIcon=new QSystemTrayIcon(this);
    trayIcon->setIcon(QIcon(":/image/tubiao.png"));
    //添加托盘菜单并为菜单添加菜单项以及菜单项被点击时的处理逻辑
    QMenu* trayMenu=new QMenu(this);
    trayMenu->addAction("显示",this,&QWidget::showNormal);//QWidget类提供的showNormal()函数可以让this当前窗口显示出来
    trayMenu->addSeparator();//添加分割线
    trayMenu->addAction("退出",this,&QQMusic::quitQQMusic);//QQMusic类提供的quitQQMusic()函数可以让该程序退出

    //为托盘添加菜单,并显示托盘
    trayIcon->setContextMenu(trayMenu);
    trayIcon->show();

    //设置最大化按钮禁止使用
    ui->max->setEnabled(false);
    //设置窗口阴影效果
    QGraphicsDropShadowEffect* shadowEffect=new QGraphicsDropShadowEffect(this);
    shadowEffect->setOffset(0,0);// 设置阴影偏移
    shadowEffect->setColor("#000000");
    shadowEffect->setBlurRadius(5);////////////////////////////////////////////////////////////////////////要修改动画有冲突
    this->setGraphicsEffect(shadowEffect);

    //设置BodyLeft中6个myForm的信息
    ui->rec->setIconAndText(":/image/rec.png","推荐",0);
    ui->radio->setIconAndText(":/image/radio.png","电台",1);
    ui->music->setIconAndText(":/image/music.png","音乐馆",2);
    ui->like->setIconAndText(":/image/like.png","我喜欢",3);
    ui->local->setIconAndText(":/image/local.png","本地下载",4);
    ui->recent->setIconAndText(":/image/recent.png","最近播放",5);

    //默认本地下载显示动画效果
    ui->local->showAnimal(true);
    //设置初始显示页面为localPage页面,并记录
    ui->stackedWidget->setCurrentIndex(4);
    currentPage=ui->localPage;

    //randomPicture();-->滚动框中设置随机图片
    srand(time(NULL));
    ui->recMusicBox->initRecBoxUi(randomPicture(),1);
    ui->supplyMusicBox->initRecBoxUi(randomPicture(),2);

    //我的音乐里三个界面设置相应的文本和图片
    ui->likePage->setCommonPageUi("我喜欢",":/image/ilikebg.png");
    ui->localPage->setCommonPageUi("本地下载",":/image/localbg.png");
    ui->recentPage->setCommonPageUi("最近播放",":/image/recentbg.png");

   //设置播放控制区域的初始图片-->暂停播放和随机播放
    ui->play->setIcon(QIcon(":/image/pause.png"));
    ui->playMode->setIcon(QIcon(":/image/random.png"));

    //创建调节音量的窗口
    volume=new VolumeTool(this);

    //创建歌词页面,并将歌词页面进行隐藏
    lrcPage=new LrcPage(this);
    lrcPage->hide();

    //创建歌词页面的动画(初始化歌词页面上移动画)
    lrcAnimation=new QPropertyAnimation(lrcPage,"geometry",this);
    lrcAnimation->setDuration(500);//设置持续时长
    lrcAnimation->setStartValue(QRect(9,9+lrcPage->height(),lrcPage->width(),lrcPage->height()));//设置动画起始帧
    lrcAnimation->setEndValue(QRect(9,9,lrcPage->width(),lrcPage->height()));//设置动画结束帧

}

//初始化数据库的方法
void QQMusic::InitSqlite()
{
    //数据库驱动加载
    sqlite=QSqlDatabase::addDatabase("QSQLITE");
    //设置数据库名称
    sqlite.setDatabaseName("QQMusic.db");
    //打开数据库
    if(!sqlite.open())
    {
        qDebug()<<"连接数据库失败"<<sqlite.lastError().text();
        return;
    }
    qDebug()<<"连接数据库成功";

    //创建存储音乐数据的表(musicInfo)
    QString sql=("create table if not exists musicInfo(\
                 id integer primary key autoincrement,\
                 musicId varchar(200) unique,\
                 musicName varchar(50),\
                 musicSinger varchar(50),\
                 albumName varchar(50),\
                 duration bigint,\
                 musicUrl varchar(256),\
                 isLike integer,\
                 isHistory integer)"
            );
    QSqlQuery query;
    if(!query.exec(sql))
    {
        qDebug()<<"创建表失败"<<query.lastError().text();
        return;
    }
    qDebug()<<"创建表成功";
}

//初始化不同页面的歌曲音乐列表(从数据库中读取数据并初始化不同页面的音乐列表)
void QQMusic::InitMusicList()
{
    //从数据库中读取music数据并初始化musicList列表
    musicList.readFromDB();
    //根据更新的musicList列表更新我喜欢页面的播放列表
    ui->likePage->setMuiscPageType(PageType::LIKE_PAGE);
    ui->likePage->reFresh(musicList);

    //根据更新的musicList列表更新本地音乐页面的播放列表
    ui->localPage->setMuiscPageType(PageType::LOCAL_PAGE);
    ui->localPage->reFresh(musicList);

    //根据更新的musicList列表更新最近更新页面的播放列表
    ui->recentPage->setMuiscPageType(PageType::RECENT_PAGE);
    ui->recentPage->reFresh(musicList);
}

//初始化媒体播放
void QQMusic::initPlayer()
{
    //初始化媒体播放类
    //实例化当前播放音乐所代表的媒体文件
    player=new QMediaPlayer(this);
    //实例化管理所有媒体文件的播放列表(用于组织媒体文件),包括一些播放模式的设置等
    playList=new QMediaPlaylist(this);

    //设置播放模式
    playList->setPlaybackMode(QMediaPlaylist::Random);
    ui->playMode->setToolTip("随机播放");
    //将播放列表设置给播放器-->不再给播放器单独设置一个播放源,而是设置一个媒体列表作为播放源
    player->setPlaylist(playList);
    //设置媒体播放的初始化音量
    player->setVolume(20);

    //播放控制区的信号和槽函数相关
    //播放和暂停按钮点击和相关槽函数相关联
    connect(ui->play,&QPushButton::clicked,this,&QQMusic::onPlayClicked);
    //媒体播放状态发生改变的信号和相关槽函数相关联
    connect(player,&QMediaPlayer::stateChanged,this,&QQMusic::onStateChanged);

    //播放上一曲按钮点击和相关槽函数相关联
    connect(ui->playUp,&QPushButton::clicked,this,&QQMusic::onPlayUp);
    //播放下一曲按钮点击和相关槽函数相关联
    connect(ui->playDown,&QPushButton::clicked,this,&QQMusic::onPlayDown);

    //播放模式按钮点击和和相关槽函数相关联
    connect(ui->playMode,&QPushButton::clicked,this,&QQMusic::onPlaybackModeClicked);
    //播放模式发生改变的信号和和相关槽函数相关联
    connect(playList,&QMediaPlaylist::playbackModeChanged,this,&QQMusic::onPlaybackModeChanged);
    //播放的歌曲发生改变的信号和相关槽函数相关联
    connect(playList,&QMediaPlaylist::currentIndexChanged,this,&QQMusic::onCurrentIndexChanged);

    //播放源持续总时长发生改变的信号和相关槽函数相关联
    connect(player,&QMediaPlayer::durationChanged,this,&QQMusic::onDurationChanged);
    //处理播放源当前播放时长发生改变的信号和相关槽函数相关联
    connect(player,&QMediaPlayer::positionChanged,this,&QQMusic::onPositionChanged);

    //播放源变化时发出的信号和相关槽函数相关联(更新歌曲名称,歌手,封面图片的显示标签以及歌词显示页面)
    connect(player,&QMediaPlayer::metaDataAvailableChanged,this,&QQMusic::onMetaDataAvailableChangedChanged);
}

//处理所有的信号和槽函数的关联
void QQMusic::connectSignalsAndSlots()
{
    //关联BtForm的信号和处理该信号的槽函数
    connect(ui->rec,&myForm::myClick,this,&QQMusic::onMyFormClick);
    connect(ui->radio,&myForm::myClick,this,&QQMusic::onMyFormClick);
    connect(ui->music,&myForm::myClick,this,&QQMusic::onMyFormClick);
    connect(ui->like,&myForm::myClick,this,&QQMusic::onMyFormClick);
    connect(ui->local,&myForm::myClick,this,&QQMusic::onMyFormClick);
    connect(ui->recent,&myForm::myClick,this,&QQMusic::onMyFormClick);

    //本地音乐三个页面中(收藏/取消收藏)操作发送的信号和处理该信号的槽函数(更新喜欢的音乐以及配置页面的音乐列表)
    connect(ui->likePage,&CommonPage::updataLikeMusic,this,&QQMusic::onupdataLikeMusic);
    connect(ui->localPage,&CommonPage::updataLikeMusic,this,&QQMusic::onupdataLikeMusic);
    connect(ui->recentPage,&CommonPage::updataLikeMusic,this,&QQMusic::onupdataLikeMusic);

    //本地音乐三个页面中点击播放全部按钮操作发送的信号和处理该信号的槽函数
    connect(ui->likePage,&CommonPage::playAll,this,&QQMusic::onPlayAll);
    connect(ui->localPage,&CommonPage::playAll,this,&QQMusic::onPlayAll);
    connect(ui->recentPage,&CommonPage::playAll,this,&QQMusic::onPlayAll);

    //本地音乐三个页面中双击歌曲Item发送的信号和处理该信号的槽函数
    connect(ui->likePage,&CommonPage::playMusicByIndex,this,&QQMusic::onPlayMusicByIndex);
    connect(ui->localPage,&CommonPage::playMusicByIndex,this,&QQMusic::onPlayMusicByIndex);
    connect(ui->recentPage,&CommonPage::playMusicByIndex,this,&QQMusic::onPlayMusicByIndex);

    //音量调节窗口中,点击静音/非静音按钮发送的信号和处理该信号的槽函数
    connect(volume,&VolumeTool::setSilence,this,&QQMusic::onSetMusicSilence);
    //音量调节窗口中,点击滑杆修改音量发送的信号和处理该信号的槽函数
    connect(volume,&VolumeTool::setMusicVolume,this,&QQMusic::onSetMusicVolume);

    //拖动进度条发送的信号和处理该信号的槽函数相关联(同步歌曲播放进度,以及当前歌曲播放时间的显示)
    connect(ui->processBar,&MusicSlider::setMusicSliderPosition,this,&QQMusic::onMusicSliderChanged);
    //点击歌词按钮发送的信号和处理该信号的槽函数相关联
    connect(ui->lrcWord,&QPushButton::clicked,this,&QQMusic::onLrcWordClicked);
}

/********************************************
 *
 * arg(i, 3, 10, QCchar('0'))
 * i：要放⼊%1位置的数据
 * 3: 三位数
 * 10：表⽰⼗进制数
 * QChar('0')：数字不够三位，前⾯⽤字符'0'填充
 *
 * ******************************************/

//准备推荐文本和推荐图片
QJsonArray QQMusic::randomPicture()
{
    QVector<QString> vecImageName;
    vecImageName<<"001.png"<<"002.png"<<"003.png"<<"004.png"<<"005.png"<<"006.png"
                <<"007.png"<<"008.png"<<"009.png"<<"010.png"<<"011.png"<<"012.png"
                <<"013.png"<<"014.png"<<"015.png"<<"016.png"<<"017.png"<<"018.png"
                <<"019.png"<<"020.png"<<"021.png"<<"022.png"<<"023.png"<<"024.png"
                <<"025.png"<<"026.png"<<"027.png"<<"028.png"<<"029.png"<<"030.png"
                <<"031.png"<<"032.png"<<"033.png"<<"034.png"<<"035.png"<<"036.png"
                <<"037.png"<<"038.png"<<"039.png";
    std::random_shuffle(vecImageName.begin(),vecImageName.end());

    QJsonArray objArray;
    for(int i=0;i<vecImageName.size();i++)
    {
        QJsonObject obj;
        obj.insert("path",":/image/rec/"+vecImageName[i]);

        QString strText=QString("推荐-%1").arg(++i,3,10,QChar('0'));
        obj.insert("text",strText);
        objArray.append(obj);
    }
    return objArray;
}

//播放指定页面(page)中下标为index的歌曲
void QQMusic::playAllOfCommonPage(CommonPage *page, int index)
{
    //更新记录当前页面的变量
    currentPage=page;
    //更新所有按钮(myFrom)的动画效果
    updateMyformAnimal();
    //清空之前playList播放列表中的歌曲
    playList->clear();
    //把当前页面对应的歌曲列表添加到当前媒体播放列表中
    page->addMusicToPlayer(musicList,playList);
    //设置播放索引,从当前索引对应的歌曲进行播放
    playList->setCurrentIndex(index);
    player->play();
}

//点击处理退出的按钮(隐藏页面,在系统托盘显示)
void QQMusic::on_exit_clicked()
{
    hide();
}

//处理点击退出菜单按钮的逻辑
void QQMusic::quitQQMusic()
{
    //更新歌曲列表里的歌曲信息到数据库中(歌曲信息写入数据库)
    musicList.writeToDB();
    //关闭数据库
    sqlite.close();
    //窗口关闭
    this->close();
}

//处理BtForm按钮点击时的逻辑
void QQMusic::onMyFormClick(int pageId)
{
    QList<myForm*> myFormList=this->findChildren<myForm*>();
    for(auto&myForm:myFormList)
    {
        if(myForm->getPageId()!=pageId)
        {
            myForm->clearBackground();
        }
    }
    qDebug()<<"更换界面: "<<pageId;
    ui->stackedWidget->setCurrentIndex(pageId);
    isDrag=false;   //点击myfrom按钮表示鼠标不能进行窗口拖拽
}


/*************************************************************
 *
 * event->globalPos()：⿏标按下事件发⽣时，光标相对于屏幕左上⻆位置
 * frameGeometry().topLeft(): ⿏标按下事件发⽣时，窗⼝左上⻆位置
 * geometry(): 不包括边框及顶部标题区的范围
 * frameGeometry(): 包括边框及顶部标题区的范围
 * event->globalPos() - frameGeometry().topLeft() 即为：⿏标按下时，窗⼝左上⻆和光标之间的距离差
 * 想要窗⼝⿏标按下时窗⼝移动，只需要在mouseMoveEvent中，让光标和窗⼝左上⻆保持相同的位置差获取⿏标相对于屏幕左上⻆的全局坐标
 *
 * ***********************************************************/

//重写鼠标按下事件-->处理鼠标拖动窗口
void QQMusic::mousePressEvent(QMouseEvent *event)
{
    (void)event;
    if(event->button()==Qt::LeftButton)
    {
        isDrag=true;//点击鼠标表示鼠标可能进行窗口拖拽
        dragPosition=event->globalPos()-this->frameGeometry().topLeft();
        return;
    }
    QWidget::mousePressEvent(event);
}

//重写鼠标移动事件-->处理鼠标拖动窗口
void QQMusic::mouseMoveEvent(QMouseEvent *event)
{
    (void)event;
    if(event->buttons()==Qt::LeftButton&&isDrag)    //isDrag用于表示鼠标是否拖拽
    {
        move(event->globalPos()-dragPosition);
        return;
    }
    QWidget::mouseMoveEvent(event);
}


//处理点击音量按钮的处理逻辑
void QQMusic::on_volume_clicked()
{
    //获取ui->volume的左上角坐标，并转换为基于屏幕的全局坐标
    QPoint point=ui->volume->mapToGlobal(QPoint(0,0));

    //计算音量调节窗口(volumeTool)的位置坐标(需要移动到的位置)
    QPoint volumeLeftTop=point-QPoint(volume->width()/2,volume->height());
    volumeLeftTop.setX(volumeLeftTop.x()+15);
    volumeLeftTop.setY(volumeLeftTop.y()+30);

    //移动窗口位置
    volume->move(volumeLeftTop);

    //窗口显示
    volume->show();
}

/**********************************
 *
 * 过滤器
 * 1.通过文件后缀fileDialog.setNameFilter ---->只能过滤一种
 *   通过文件后缀fileDialog.setNameFilters ---->过滤多种
 * 2.通过文件的MIME类型过滤
 *
 * **********************************/

//处理添加本地音乐按钮的处理逻辑
void QQMusic::on_addLocal_clicked()
{
    //创建一个对话框
    QFileDialog fileDialog(this);
    fileDialog.setWindowTitle("添加本地音乐");        //设置窗口标题
    //创建一个打开格式的文件对话框
    fileDialog.setAcceptMode(QFileDialog::AcceptOpen);
    //设置对话框模式-->一次可打开多个文件
    fileDialog.setFileMode(QFileDialog::ExistingFiles);
    //设置文件对话框的过滤器
    //setNameFilter设置过滤器(按文件后缀进行过滤),一次只能设置一个,且只生效一个,最后设置的生效
    //setNameFilters设置过滤器(按文件后缀进行过滤),可设置多个,都生效
    //fileDialog.setNameFilter("代码文件(*.h *.c *.cpp)");          //按照后缀进行过滤不方便,可能漏写某一后缀名
    //设置对话框的MIME过滤器
    QStringList mimeList;
    mimeList<<"application/octet-stream";           //相当于All*(没有进行过滤)
    fileDialog.setMimeTypeFilters(mimeList);

    //设置默认打开路径
    QDir dir(QDir::currentPath());              //通过QDir类提供的currentPath()方法获取应用程序相对当前路径
    dir.cdUp();                                 //返回当前路径的上层目录
    QString url=dir.path()+"/QQMusic/Music/";   //设置当前路径在工程目录底下的音乐文件保存处
    fileDialog.setDirectory(url);               //设置文件对话框默认打开路径

    //打开模态对话框
    if(fileDialog.exec()==QDialog::Accepted)    //在模态对话框中选择"打开"按钮
    {
        QList<QUrl> fileUrls = fileDialog.selectedUrls();//获取选中的所有文件的url路径
        musicList.addMusicByUrl(fileUrls);               //通过音乐文件的Url路径往音乐列表中添加音乐文件,musicList中管理的是解析之后的Music对象

        //将CommonPage切换到本地下载的页面中
        ui->stackedWidget->setCurrentIndex(4);
        //把歌曲信息更新到CommonPage页面的ListWidget中(更新到本地音乐列表中)
        ui->localPage->reFresh(musicList);

    }

    //添加完本地音乐后,当前页面(本地下载页面)的歌曲列表添加到媒体列表中
    ui->localPage->addMusicToPlayer(musicList,playList);
}

//更新喜欢的音乐以及配置页面的音乐列表
void QQMusic::onupdataLikeMusic(bool isLike, const QString &musicId)
{
    auto it=musicList.findMusicById(musicId);
    //修改对应歌曲Id的歌曲状态
    if(it!=musicList.end())
    {
        it->setIsLike(isLike);
    }
    //更新Page页面的音乐列表
    ui->likePage->reFresh(musicList);
    ui->localPage->reFresh(musicList);
    ui->recentPage->reFresh(musicList);
}

/////////////////////////////////////////////////////////////////
//播放控制区的槽函数////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////

//处理点击播放和暂停按钮的处理逻辑-->改变媒体播放的状态
void QQMusic::onPlayClicked()
{
    if(player->state()==QMediaPlayer::PlayingState)
    {
        player->pause();
    }
    else if(player->state()==QMediaPlayer::PausedState)
    {
        player->play();
    }
    else if(player->state()==QMediaPlayer::StoppedState)
    {
        player->play();
    }
    else
        qDebug()<<"播放出现故障，请抓紧维修";
}

//处理媒体播放状态发生改变的处理逻辑-->改变播放/暂停按钮图片的切换
void QQMusic::onStateChanged()
{
    if(player->state()==QMediaPlayer::PlayingState)
    {
        ui->play->setIcon(QIcon(":/image/play.png"));

    }
    else
    {
        ui->play->setIcon(QIcon(":/image/pause.png"));
    }
}

//处理点击上一曲按钮的处理逻辑-->让媒体列表切换上一曲
void QQMusic::onPlayUp()
{
    playList->previous();
}

//处理点击下一曲按钮的处理逻辑-->让媒体列表切换下一曲
void QQMusic::onPlayDown()
{
    playList->next();
}

//处理点击播放模式按钮的处理逻辑-->改变媒体播放的模式
void QQMusic::onPlaybackModeClicked()
{
    if(playList->playbackMode()==QMediaPlaylist::Random)
    {
        playList->setPlaybackMode(QMediaPlaylist::Loop);
        ui->playMode->setToolTip("列表循环");
    }
    else if(playList->playbackMode()==QMediaPlaylist::Loop)
    {
        playList->setPlaybackMode(QMediaPlaylist::CurrentItemInLoop);
        ui->playMode->setToolTip("单曲循环");
    }
    else if(playList->playbackMode()==QMediaPlaylist::CurrentItemInLoop)
    {
        playList->setPlaybackMode(QMediaPlaylist::Random);
        ui->playMode->setToolTip("随机播放");
    }
    else
        qDebug()<<"暂未支持,敬请期待";
}

//处理媒体播放模式发生改变的处理逻辑-->改变播放模式按钮图片的切换
void QQMusic::onPlaybackModeChanged(QMediaPlaylist::PlaybackMode playbackMode)
{
    if(playbackMode==QMediaPlaylist::Random)
    {
        ui->playMode->setIcon(QIcon(":/image/random.png"));
    }
    else if(playbackMode==QMediaPlaylist::Loop)
    {
        ui->playMode->setIcon(QIcon(":/image/loop.png"));
    }
    else if(playbackMode==QMediaPlaylist::CurrentItemInLoop)
    {
        ui->playMode->setIcon(QIcon(":/image/CurrentItemInLoop.png"));
    }
    else
        qDebug()<<"暂未支持,敬请期待";
}

//处理点击播放所有按钮的处理逻辑-->播放CommomPage页面中的所有歌曲,默认从第0首开始播放
void QQMusic::onPlayAll(PageType pageType)
{
    //确定播放全部信号是哪个页面发出的,CommonPage* page指针指向发出信号的页面,page记录的就是要播放的页面
    CommonPage* page=nullptr;
    switch (pageType)
    {
    case LIKE_PAGE:
        page=ui->likePage;
        break;
    case LOCAL_PAGE:
        page=ui->localPage;
        break;
    case RECENT_PAGE:
        page=ui->recentPage;
        break;
    default:
        qDebug()<<"暂未支持，敬请期待";
    }
    //播放对应页面(page)的所有歌曲,默认从第0首开始播放
    playAllOfCommonPage(page,0);
}

//处理双击歌曲Item的处理逻辑-->播放CommomPage页面中的被双击的歌曲
void QQMusic::onPlayMusicByIndex(CommonPage *page, int index)
{
    //播放对应页面(page)中被双击的歌曲,被双击的歌曲索引为index
    playAllOfCommonPage(page,index);
}

//处理当前播放的歌曲发送改变的处理逻辑-->得知那首歌曲被播放后更新歌曲的播放历史属性,并更新播放历史页面
void QQMusic::onCurrentIndexChanged(int index)
{
    //更新记录当前媒体播放源在媒体列表中的索引的对象
    currentPlayMusicIndex=index;
    //通过歌曲索引获取歌曲Id
    QString musicId=currentPage->getMusicIdByIndex(index);
    //设置当前播播放歌曲的isHistory属性为true
    auto it=musicList.findMusicById(musicId);
    if(it!=musicList.end())
    {
        it->setIsHistory(true);
    }
    //更新最近播放页面(recentPage)
    ui->recentPage->reFresh(musicList);
}

//处理点击静音/非静音按钮的处理逻辑-->得知静音/非静音按钮点击后，根据VolumeTool的isMuted属性设置媒体是否静音
void QQMusic::onSetMusicSilence(bool isMuted)
{
    player->setMuted(isMuted);
}

//处理调解音量的处理逻辑-->得知点击滑杆修改音量后，根据VolumeTool的volumeRatio属性设置媒体当前的音量
void QQMusic::onSetMusicVolume(int volume)
{
    player->setVolume(volume);
}

//处理播放源持续总时长发生改变(媒体切换)的处理逻辑-->更新总时间的显示标签
void QQMusic::onDurationChanged(qint64 duration)
{
    //duration为歌曲的总时长,单位为毫秒
    totalDuration=duration;
    //需要将整形的总时长转化为多少分多少秒，占两位,十进制,不足两位的用字符'0'占用
    ui->totalTime->setText(QString("%1:%2").arg(duration/1000/60,2,10,QChar('0'))
                           .arg(duration/1000%60,2,10,QChar('0')));
}

//处理播放源当前播放时长发生改变的处理逻辑-->更新当前时间的显示标签以及进度条和歌词的当前显示
void QQMusic::onPositionChanged(qint64 position)
{
    //更新当前时间的显示标签
    ui->currentTime->setText(QString("%1:%2").arg(position/1000/60,2,10,QChar('0'))
                             .arg(position/1000%60,2,10,QChar('0')));
    //根据当前时间更新进度条
    ui->processBar->setStep((float)position/(float)totalDuration);
    //根据当前时间更新歌词显示
    if(playList->currentIndex()>=0)
    {
        lrcPage->ShowLineLrcWord(position);
    }
}

//处理拖动进度条导致歌曲播放进度以及当前时间显示标签改变的处理逻辑
void QQMusic::onMusicSliderChanged(float ratio)
{
    //更新当前时间显示标签
    qint64 currentTime=(qint64)(ratio*totalDuration);
    ui->currentTime->setText(QString("%1:%2").arg(currentTime/1000/60,2,10,QChar('0'))
                             .arg(currentTime/1000%60,2,10,QChar('0')));
    //更新歌曲播放进度
    player->setPosition(currentTime);
}

//处理播放源变化时更新相应的媒体元数据的显示标签(歌曲名称,歌手,封面图片,歌词的同步)
void QQMusic::onMetaDataAvailableChangedChanged(bool available)
{
    (void)available;
    qDebug()<<"歌曲更换";
    //获取当前歌曲的歌曲名称以及歌曲作者(可通过媒体播放源的metaData()函数获取相应的元数据)
    QString musicName=player->metaData("Title").toString();
    QString singer=player->metaData("Author").toStringList().join(",");
    //如果元数据为空,就需要根据索引找到对应的歌曲文件对象,进行元数据(歌曲名称以及歌曲作者)的获取
    if(musicName.isEmpty())
    {
        auto currentMusic=musicList.findMusicById(currentPage->getMusicIdByIndex(currentPlayMusicIndex));
        if(currentMusic!=musicList.end())
        {
            musicName=currentMusic->getMusicName();
            singer=currentMusic->getMusicSinger();
        }
    }
    //更新元数据(歌曲名称以及歌曲作者)显示标签
    ui->musicName->setText(musicName);
    ui->musicSinger->setText(singer);

    //更新封面图片-->更新播放区域的图片和CommonPage的图片
    QVariant coverImage=player->metaData("ThumbnailImage");
    if(coverImage.isValid())    //isValid()用于检测返回的元数据是否是已知类型(是否成功获取图片)
    {
        //获取封面图片成功
        QImage image=coverImage.value<QImage>();
        ui->musicCover->setPixmap(QPixmap::fromImage(image));
        currentPage->setImageLabel(QPixmap::fromImage(image));
    }
    else
    {
        //封面图片获取失败
        QString image=":/image/rec/038.png";
        ui->musicCover->setPixmap(image);
        currentPage->setImageLabel(image);
    }
    //设置封面图片的填充方式为自适应填充
    ui->musicCover->setScaledContents(true);

    //解析歌曲的LRC歌词
    QString musicIndex=currentPage->getMusicIdByIndex(currentPlayMusicIndex);
    auto it=musicList.findMusicById(musicIndex);
    if(it!=musicList.end())
    {
        //解析Lrc文件
        lrcPage->parseLrc(it->getLrcFilePath());//getLrcFilePath是只读函数不可以修改所以parseLrc不能&
        //更新歌曲页面的歌曲名称和歌曲作者的显示
        lrcPage->ShowLrcMusicName(it->getMusicName());
        lrcPage->ShowLrcMusicSinger(it->getMusicSinger());
    }
}

//处理点击歌词按钮的处理逻辑-->通过动画缓慢显示歌词页面
void QQMusic::onLrcWordClicked()
{
    lrcPage->show();
    lrcAnimation->start();
}


//处理点击最小化按钮的处理逻辑
void QQMusic::on_min_clicked()
{
    showMinimized();
}

//处理点击换肤按钮的处理逻辑
void QQMusic::on_skin_clicked()
{
    QMessageBox::information(this,"温馨提示","未支持，请期待！");
}

//更新所有按钮(myFrom)的动画效果-->动画效果标记正在播放歌曲的页面
void QQMusic::updateMyformAnimal()
{
    //获取当前页面在stackedWidget中的索引
    int index=ui->stackedWidget->indexOf(currentPage);
    if(index==-1)
    {
        qDebug()<<"无此页面";
        return;
    }
    //获取qqmusic界面上所有的myForm
    QList<myForm*> myForms=this->findChildren<myForm*>();
    for(auto myForm:myForms)
    {
        //如果myForm中保存的PageId和当前页面在stackedWidget中的索引相同,说明该页面歌曲正在播放,其动画效果要显示
        //                                                   不同,,说明该页面歌曲不在播放,其动画效果要隐藏
        if(myForm->getPageId()==index)
        {
            myForm->showAnimal(true);
        }
        else
        {
            myForm->showAnimal(false);
        }
    }
}
